package tc.jv.task2;

import java.util.Locale;

public class Vector implements Cloneable
{
	private int size;
	private double data[];
	
	// CONSTRUCTORS

	public Vector(int length)
	{
		this.size = length;
		data = new double[length];
	}
	
	// ACCESSORS
	
	public int size()
	{
		return size;
	}
	
	public double get(int index)
	{
		return isValidIndex(index) ? data[index] : null;
	}
	
	public void set(int index, double value)
	{
		if (isValidIndex(index))
			data[index] = value;
	}
	
	// METHODS
	
	public void print()
	{		
		System.out.println(toString());
	}
	
	public void print(int pcs)
	{		
		System.out.println(toString(pcs));
	}
	
	@Override
	public String toString()
	{
		String s      = "",
			   format = "%f\t";
				
		for (Double d : data)
			s = s + String.format(Locale.US, format, d);
		return s;
	}
	
	public String toString(int pcs)
	{
		String s      = "",
			   format = String.format("%%.%df\t", pcs); // %.<precision>f
			
		for (Double d : data)
			s = s + String.format(Locale.US, format, d);
		return s;
	}
	
	@Override
	public boolean equals(Object obj)
	{
		if (obj instanceof Vector)
		{
			Vector v = (Vector) obj;
			if (this.size == v.size)
			{
				boolean e = true;
				for (int i = 0; e == true && i < size; i++)
					e &= (data[i] == v.data[i]);
				return e;
			}				
			else
				return false;
		}
		else
			return false;
	}
	
	@Override
	public Vector clone()
	{
		Vector v = new Vector(size);
		v.data = this.data.clone();
		return v;
	}
	
	public boolean fill(double[] array)
	{
		return fill(array, 0);
	}
	
	public boolean fill(double[] array, int position)
	{
		if (isValidIndex(position + array.length - 1))
		{
			for (int i = 0; i < array.length; i++)
				data[i+position] = array[i];
			return true;
		}
		else
			return false;
	}
	
	public boolean fill(Vector v)
	{
		return fill(v.data);
	}
	
	public boolean fill(Vector v, int position)
	{
		return fill(v.data, position);
	}
	
	public double min()
	{
		double f = data[0];
		for (int i = 1; i < size; i++)
			if (data[i] < f)
				f = data[i];
		return f;
	}
	
	public double max()
	{
		double f = data[0];
		for (int i = 1; i < size; i++)
			if (data[i] > f)
				f = data[i];
		return f;
	}

	public boolean add(Vector v)
	{
		return add(v, 0);
	}
	
	public boolean add(Vector v, int position)
	{
		if (isValidIndex(position + v.size - 1))
		{
			for (int i = 0; i < v.size; i++)
				data[i+position] += v.data[i];
			return true;
		}
		else
			return false;			
	}
	
	public boolean multiply(double num)
	{
		if (!Double.isNaN(num) && !Double.isInfinite(num))
		{
			for (int i = 0; i < size; i++)
				data[i] *= num;
			return true;
		}
		else
			return false;
	}

	protected boolean isValidIndex(int index)
	{
		return index >= 0 && index < size;
	}

	public long[] compare(Vector v)
	{		
		if (v.size == this.size)
		{
			long[] c = new long[size];
			double d;
			for (int i = 0; i < size; i++)
			{
				d = this.data[i] - v.data[i];
				if (d != 0)
				{
					d = (d > 0) ? Math.ceil(d) : Math.floor(d);
					c[i] = (long) d / Math.abs((long) d);
				}
				else
					c[i] = 0;
			}
			return c;
		}
		else
			return null;
	}

	public static Vector add(Vector v1, Vector v2)
	{
		Vector nv = v1.clone();
		return nv.add(v2) ? nv : null;
	}
	
	public static Vector multiply(Vector v, double num)
	{
		Vector nv = v.clone();
		return nv.multiply(num) ? nv : null;
	}
	
}
